package com.cskaoyan.wordmemorize.service.impl.app;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cskaoyan.wordmemorize.annotation.OperateLog;
import com.cskaoyan.wordmemorize.converter.ReviewConverter;
import com.cskaoyan.wordmemorize.dao.entity.UserRevStatisticsDO;
import com.cskaoyan.wordmemorize.dao.entity.UserVocRevDO;
import com.cskaoyan.wordmemorize.dao.mapper.UserRevStatisticsMapper;
import com.cskaoyan.wordmemorize.dao.mapper.UserVocRevMapper;
import com.cskaoyan.wordmemorize.dto.admin.PageDTO;
import com.cskaoyan.wordmemorize.dto.app.DownLoadUserReviewDTO;
import com.cskaoyan.wordmemorize.dto.app.UserReviewStatisticsDTO;
import com.cskaoyan.wordmemorize.dto.app.UserVocRevDTO;
import com.cskaoyan.wordmemorize.request.PageRequest;
import com.cskaoyan.wordmemorize.request.UserReviewDataCommand;
import com.cskaoyan.wordmemorize.request.UserReviewStatisticsCommand;
import com.cskaoyan.wordmemorize.request.UserVocRevCommand;
import com.cskaoyan.wordmemorize.service.UserReviewService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.List;

@Service
public class UserReviewServiceImpl implements UserReviewService {
    @Autowired
    UserVocRevMapper userVocRevMapper;


    @Autowired
    ReviewConverter reviewConverter;

    // 1.APP端添加复习单词
    @Override
    @Transactional
    public void addUserRovRev(List<Long> vocIds, Long userId) {
        // 每个单词创建一个有默认值的记录
        for (Long vocId : vocIds) {
            UserVocRevDO userVocRevDO = new UserVocRevDO();
            userVocRevDO.setVocId(vocId);
            userVocRevDO.setUserId(userId);
            userVocRevDO.setFactor(1.4);
            userVocRevDO.setReviewInterval(1);
            // 如果是第一次复习, 则设置下次复习时间为明天
            userVocRevDO.setNextReviewDate(LocalDate.now().plusDays(1));
            userVocRevDO.setType(0);
            userVocRevDO.setFamiliarity(0);
            userVocRevDO.setConsecutiveFailCount(0);
            userVocRevDO.setTotalReview(0);
            // 保存到数据库中
            // TODO: 保存到数据库中
            // 如果数据库中已经存在该单词的记录, 则更新该记录
            // 如果数据库中不存在该单词的记录, 则插入该记录
            // 先查询数据库中是否存在该单词的记录
            QueryWrapper<UserVocRevDO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("voc_id", vocId);
            queryWrapper.eq("user_id", userId);
            if (userVocRevMapper.exists(queryWrapper)) {
                // 如果数据库中已经存在该单词的记录, 则更新该记录
                userVocRevMapper.update(userVocRevDO, queryWrapper);
            } else {
                // 如果数据库中不存在该单词的记录, 则插入该记录
                userVocRevMapper.insert(userVocRevDO);
            }
        }
    }



    // 2.同步APP端复习数据
    @Autowired
    UserRevStatisticsMapper userRevStatisticsMapper;
    @Override
    @Transactional
    public void synchronizeUserReviewData(UserReviewDataCommand command, Long userId) {
        List<UserVocRevCommand> vocRevCommands = command.getVocRevCommands();
        // TODO: 转换为DO对象
        List<UserVocRevDO> userVocRevDOs = reviewConverter.userVocRevCommands2DOs(vocRevCommands);
        for (UserVocRevDO userVocRevDO : userVocRevDOs) {
            userVocRevDO.setUserId(userId);
        }
        // TODO: 保存到数据库中 (更新表user_voc_rev)
        userVocRevMapper.insert(userVocRevDOs);

        UserReviewStatisticsCommand revStatisticsCommand = command.getRevStatisticsCommand();
        // TODO: 转换为DO对象
        UserRevStatisticsDO userRevStatisticsDO = reviewConverter.userRevStatisticsCommand2DO(revStatisticsCommand);
        userRevStatisticsDO.setUserId(userId);
        // TODO: 保存到数据库中 (更新表user_rev_statistics)
        userRevStatisticsMapper.insert(userRevStatisticsDO);

    }

    // 3.下载所有复习数据(首次登录时)
    @Override
    public DownLoadUserReviewDTO downloadUserReviewData(PageRequest pageRequest, Long userId) {

        // 1.分页查询数据库中表user_voc_rev的数据
        Page<UserVocRevDO> userVocRevDOPage = new Page<>(pageRequest.getPageNum(), pageRequest.getCount());
        // 得到user_voc_rev表中的数据列表和总条数(user_id = userId)
        QueryWrapper<UserVocRevDO> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("user_id", userId);

        List<UserVocRevDO> userVocRevDOList
                = userVocRevMapper.selectPage(userVocRevDOPage, queryWrapper1).getRecords();

        long userVocRevDOListTotal = userVocRevDOPage.getTotal();

        PageDTO<UserVocRevDTO> userVocRevDTOPageDTO
                = reviewConverter.userVocRevPage2PageDTO(userVocRevDOList, userVocRevDOListTotal);


        // 2.分页查询数据库中表user_rev_statistics的数据
        Page<UserRevStatisticsDO> userRevStatisticsDOPage = new Page<>(pageRequest.getPageNum(), pageRequest.getCount());
        // 得到user_rev_statistics表中的数据列表和总条数(user_id = userId)
        QueryWrapper<UserRevStatisticsDO> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("user_id", userId);

        List<UserRevStatisticsDO> userRevStatisticsDOList
                = userRevStatisticsMapper.selectPage(userRevStatisticsDOPage, queryWrapper2).getRecords();

        long userRevStatisticsDOListTotal = userRevStatisticsDOPage.getTotal();

        PageDTO<UserReviewStatisticsDTO> userReviewStatisticsDTOPageDTO
                = reviewConverter.userRevStatistcsPage2PageDTO(userRevStatisticsDOList, userRevStatisticsDOListTotal);


        // 3.将两个PageDTO对象封装到DownLoadUserReviewDTO对象中
        DownLoadUserReviewDTO downLoadUserReviewDTO = new DownLoadUserReviewDTO();
        downLoadUserReviewDTO.setUserVocRevPage(userVocRevDTOPageDTO);
        downLoadUserReviewDTO.setUserReviewStatisticsPage(userReviewStatisticsDTOPageDTO);
        return downLoadUserReviewDTO;
    }
}
